package com.superbytecode.stencil.enums;

import com.superbytecode.stencil.utils.StringUtil;
import lombok.Getter;

import java.util.Arrays;
import java.util.Objects;

/**
 * All rights Reserved, Designed By www.super-master.com
 *
 * @ProjectName: code-stencil
 * @Package: com.superbytecode.stencil.definitions
 * @ClassName: SQLTypeEnum
 * @Description: []
 * <p> </p>
 * @Author: [Lance Ting]
 * @Date: 2024/10/11 20:08
 * @Version: V1.0
 * @Copyright: 2024 www.super-master.cn Inc. All rights reserved.
 * TODO: 注意,本文件Lance Ting所作,如果转载或使用请标明具体出处!
 **/
@Getter
public enum SQLTypeEnum {
    /**
     * Bit类型
     *
     * @see: mysql->    bit
     * @see: oracle->   bit
     * @see: postgres-> bit
     * @see: sqlserver->bit
     **/
    BIT("bit", "bit"),
    /**
     * boolean类型
     *
     * @see: mysql->    boolean
     * @see: oracle->   boolean
     * @see: postgres-> boolean
     * @see: sqlserver->boolean
     **/
    BOOLEAN("boolean", "boolean"),
    /**
     * tinyint类型
     *
     * @see: mysql->    tinyint
     * @see: oracle->   tinyint
     * @see: postgres-> int2, serial2", smallint
     * @see: sqlserver->tinyint
     **/
    TINYINT("tinyint", "tinyint,int2,serial2,smallint"),//
    /**
     * smallint类型
     *
     * @see: mysql->    smallint
     * @see: oracle->   无
     * @see: postgres-> 无
     * @see: sqlserver->smallint
     **/
    SMALLINT("smallint", "smallint"),
    /**
     * int类型
     *
     * @see: mysql->    integer，int
     * @see: oracle->   integer,int
     * @see: postgres-> integer,int4,serial4
     * @see: sqlserver->integer，int
     **/
    INT("int", "int,integer,int4,serial4"),
    /**
     * bigint类型
     *
     * @see: mysql->    bigint
     * @see: oracle->   long
     * @see: postgres-> bigint,int8,serial8
     * @see: sqlserver->bigint
     **/
    BIGINT("bigint", "bigint,long,int8,serial8"),
    /**
     * float类型
     *
     * @see: mysql->    float
     * @see: oracle->   float
     * @see: postgres-> float,real
     * @see: sqlserver->float,real
     **/
    FLOAT("float", "float,real"),
    /**
     * double类型
     *
     * @see: mysql->    double
     * @see: oracle->   double
     * @see: postgres-> double
     * @see: sqlserver->double
     **/
    DOUBLE("double", "double"),
    /**
     * decimal类型
     *
     * @see: mysql->    decimal
     * @see: oracle->   decimal
     * @see: postgres-> decimal,numeric
     * @see: sqlserver->decimal,numeric,money,smallmoney
     **/
    DECIMAL("decimal", "decimal,numeric,money,smallmoney"),
    /**
     * CHAR类型
     *
     * @see: mysql->    char,varchar,text
     * @see: oracle->   char,varchar,text,nchar,varchar2,nvarchar2
     * @see: postgres-> char,varchar,text,character,json
     * @see: sqlserver->char,varchar,text,nchar,ntext,nvarchar
     **/
    VARCHAR("varchar", "char,varchar,text,nchar,varchar2,nvarchar,nvarchar2,character,json"),
    /**
     * DATE类型
     *
     * @see: mysql->    date, time, datetime, timestamp
     * @see: oracle->   date, time, datetime, timestamp
     * @see: postgres-> date, time, datetime, timestamp
     * @see: sqlserver->date, time, datetime, timestamp,datetime2,smalldatetime,datetimeoffset
     **/
    DATETIME("datetime", "date, time, datetime, timestamp,datetime2,smalldatetime,datetimeoffset"),
    /**
     * blob类型
     *
     * @see: mysql->    blob
     * @see: oracle->   blob
     * @see: postgres-> blob
     * @see: sqlserver->blob,binary,varbinary
     **/
    BLOB("blob", "blob,binary,varbinary"),
    ;

    // -----------------------------------------------------------------------------------------------------------------

    /**
     * 解析不同数据库column列通用类型
     *
     * @param originalType 数据列定义sql类型
     * @return 通用类型
     */
    public static String ofGenericType(String originalType) {
        SQLTypeEnum sqlTypeEnum = Arrays.stream(values())
                // 匹配原始入参
                .filter(v -> Arrays.stream(v.getScope().split(","))//匹配规则
                        .anyMatch(s -> StringUtil.equalsIgnoreCase(s.trim(), originalType))//
                ).findAny()//
                .orElseThrow(() -> new IllegalArgumentException("SQL no support column type: " + originalType));

        return sqlTypeEnum.getCategory();
    }

    public static boolean match(String originalType, SQLTypeEnum setting) {
        return Objects.equals(SQLTypeEnum.ofGenericType(originalType), setting.getCategory());
    }

    // -----------------------------------------------------------------------------------------------------------------
    /**
     * 数据类型分类
     *
     * @see: {@link JavaTypeEnum}#category
     * @see: {@link MyBatisTypeEnum}#category
     */
    final private String category;
    /**
     * 数据库列类型范围
     * <p>不同数据库类型存在差异性</p>
     */
    final private String scope;

    SQLTypeEnum(String category, String scope) {
        this.category = category;
        this.scope = scope;
    }
}